﻿using System;
using System.Collections.Generic;
using CppUT.NativeMethods;
using System.Runtime.InteropServices;

namespace CppUT
{
    namespace Common
    {
        public class TestMetaData
        {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="aTestRunner">Loaded test runner.</param>
            public TestMetaData(IntPtr aTestRunner)
            {
                _testRunner = aTestRunner;
                _allTests = new List<string>();
            }

            public void Refresh()
            {
                var testsRoot = CppUnitModel.GetTestRoot(_testRunner);
                VisitTest(testsRoot);
            }

            public List<string> GetTests()
            {
                return _allTests;
            }

            private void VisitTest(IntPtr testsRoot)
            {
                var testPtrQueue = new Queue<IntPtr>();

                //  Push root test suite to the queue
                testPtrQueue.Enqueue(testsRoot);

                //  Process all current elements in the queue
                while (testPtrQueue.Count != 0)
                {
                    var testPtr = testPtrQueue.Dequeue();

                    //  For each element in the queue, extract test name, add it to the list
                    var testName = CppUnitModel.GetTestName(testPtr);
                    var strTestName = Marshal.PtrToStringAnsi(testName);
                    CppUnitModel.DeleteStringBuffer(testName);
                    _allTests.Add(strTestName);

                    //  Add all children to the queue for processing
                    int numberOfTests = CppUnitModel.GetNoOfChildTests(testPtr);
                    for (int nChildIndex = 0; nChildIndex < numberOfTests; ++nChildIndex)
                    {
                        testPtrQueue.Enqueue(CppUnitModel.GetTestChild(testPtr, nChildIndex));
                    }
                }
            }

            private List<string> _allTests;
            private IntPtr _testRunner;
        }
    }
}